<!-- wyf 2022-1-25 -->
<template>
  <a-tree-select
    :ref="treeSelectRef"
    v-model:value="value1"
    v-model:treeExpandedKeys="treeExpandedKeys1"
    v-model:searchValue="searchValue1"
    :placeholder="placeholder"
    :tree-data="treeData1"
    :multiple="multiple"
    :allow-clear="allowClear"
    :tree-default-expand-all="treeDefaultExpandAll"
    :tree-default-expanded-keys="treeDefaultExpandedKeys"
    :show-search="showSearch"
    :default-value="defaultValue"
    :dropdown-class-name="dropdownClassName"
    :dropdown-match-select-width="dropdownMatchSelectWidth"
    :dropdown-style="dropdownStyle"
    :filter-tree-node="filterTreeNode"
    :get-popup-container="getPopupContainer"
    :list-height="listHeight"
    :load-data="loadData"
    :tree-check-strictly="treeCheckStrictly"
    :tree-line="treeLine"
    :tree-node-filter-prop="treeNodeFilterProp"
    :tree-node-label-prop="treeNodeLabelProp1"
    :virtual="virtual"
    :tree-checkable="treeCheckable"
    :label-in-value="labelInValue"
    :max-tag-count="maxTagCount"
    :field-names="fieldNames1"
    :tree-data-simple-mode="treeDataSimpleMode"
    :is-choose-last="isChooseLast1"
  >
    <slot />
    <template v-if="$slots.maxTagPlaceholder" #maxTagPlaceholder="node">
      <slot name="maxTagPlaceholder" :node="node" />
    </template>
    <template v-if="$slots.suffixIcon" #suffixIcon="node">
      <slot name="suffixIcon" :node="node" />
    </template>
    <template v-if="$slots.title" #title="title">
      <slot name="title" :title="title" />
    </template>
    <template v-if="$slots.searchPlaceholder" #searchPlaceholder="node">
      <slot name="searchPlaceholder" :node="node" />
    </template>
  </a-tree-select>
</template>

<script>
import { defineComponent, computed, watch, ref } from 'vue'
import { TreeSelect } from 'ant-design-vue'
export default defineComponent({
  name: 'ZTreeSelect',
  components: {
    ATreeSelect: TreeSelect
  },
  props: {
    treeSelectRef: {
      type: String,
      default: 'treeSelect'
    },
    value: {
      type: [String, Array, Number],
      default: undefined
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    treeData: {
      type: Array,
      default: undefined
    },
    multiple: {
      type: Boolean,
      default: false
    },
    allowClear: {
      type: Boolean,
      default: false
    },
    treeDefaultExpandAll: {
      type: Boolean,
      default: undefined
    },
    showSearch: {
      type: Boolean,
      default: false
    },
    defaultValue: {
      type: [String, Array],
      default: undefined
    },
    treeDefaultExpandedKeys: {
      type: [String, Array],
      default: undefined
    },
    dropdownClassName: {
      type: String,
      default: undefined
    },
    dropdownMatchSelectWidth: {
      type: [Boolean, Number],
      default: undefined
    },
    dropdownStyle: {
      type: Object,
      default: undefined
    },
    filterTreeNode: {
      type: [Boolean, Function],
      default: undefined
    },
    getPopupContainer: {
      type: Function,
      default: undefined
    },
    listHeight: {
      type: Number,
      default: 256
    },
    loadData: {
      type: Function,
      default: undefined
    },
    treeCheckStrictly: {
      type: Boolean,
      default: false
    },
    treeExpandedKeys: {
      type: Array,
      default: undefined
    },
    treeLine: {
      type: [Boolean, Object],
      default: false
    },
    treeNodeFilterProp: {
      type: String,
      default: 'value'
    },
    treeNodeLabelProp: {
      type: String,
      default: 'title'
    },
    virtual: {
      type: Boolean,
      default: true
    },
    treeCheckable: {
      type: Boolean,
      default: false
    },
    labelInValue: {
      type: Boolean,
      default: false
    },
    maxTagCount: {
      type: Number,
      default: undefined
    },
    searchValue: {
      type: String,
      default: undefined
    },
    fieldNames: {
      type: Object,
      default() {
        return {
          children: 'children',
          label: 'title',
          key: 'key',
          value: 'value'
        }
      }
    },
    treeDataSimpleMode: {
      type: [Boolean, Array],
      default: false
    },
    isChooseLast: {
      type: Boolean,
      default: undefined
    }
  },
  setup(props, _ref) {
    const value1 = computed({
      get() {
        return props.value
      },
      set(val) {
        _ref.emit('update:value', val)
      }
    })

    const fieldNames1 = computed(() => ({ children: 'children', title: 'title', key: 'key', ...props.fieldNames }))

    const treeExpandedKeys1 = computed({
      get() {
        return props.treeExpandedKeys
      },
      set(val) {
        _ref.emit('update:treeExpandedKeys', val)
      }
    })
    const searchValue1 = computed({
      get() {
        return props.searchValue
      },
      set(val) {
        _ref.emit('update:searchValue', val)
      }
    })

    const treeData1 = ref(props.treeData)

    const treeNodeLabelProp1 = computed(() => {
      if (props.treeNodeLabelProp !== 'title') {
        return props.treeNodeLabelProp
      } else {
        return fieldNames1.value.title
      }
    })

    const isChooseLast1 = computed(() => props.isChooseLast)

    const mapTreeData = (arr) => {
      const array = [].concat(arr)
      array.forEach(item => {
        const children = item[fieldNames1.value['children']]
        if (children && children.length > 0) {
          item.selectable = !isChooseLast1.value
          item[fieldNames1.value['children']] = mapTreeData(children)
        } else {
          item.disabled = false
        }
      })
      return array
    }

    watch(() => props.isChooseLast, () => {
      treeData1.value = mapTreeData(props.treeData)
    })

    watch(() => props.treeData, () => {
      treeData1.value = mapTreeData(props.treeData)
    })

    if (props.isChooseLast) {
      treeData1.value = mapTreeData(props.treeData)
    }

    return {
      value1,
      fieldNames1,
      treeExpandedKeys1,
      searchValue1,
      isChooseLast1,
      treeData1,
      treeNodeLabelProp1
    }
  }
})
</script>
